package com.lvy.hczn.front.business.service.impl;

import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.thread.ThreadUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lvy.hczn.front.business.common.CacheConstants;
import com.lvy.hczn.front.business.common.Constants;
import com.lvy.hczn.front.business.mapper.*;
import com.lvy.hczn.front.business.service.*;
import com.lvy.hczn.front.common.constant.MqConstants;
import com.lvy.hczn.front.common.core.text.Convert;
import com.lvy.hczn.front.common.utils.DictUtils;
import com.lvy.hczn.front.common.utils.ShiroUtils;
import com.lvy.hczn.front.system.domain.business.*;
import com.lvy.hczn.front.business.dto.Param;
import com.lvy.hczn.front.common.core.redis.RedisCache;
import com.lvy.hczn.front.common.exception.UtilException;
import com.lvy.hczn.front.system.mapper.SpuMapper;
import com.lvy.hczn.front.system.service.TemperatureZoneService;
import com.lvy.hczn.mq.rocket.ParamInfo;
import com.lvy.hczn.mq.rocket.ProducerUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@Slf4j
@Service
@Transactional(rollbackFor = Exception.class)
public class GoodsBoxServiceImpl extends ServiceImpl<GoodsBoxMapper, GoodsBox> implements GoodsBoxService {

    @Autowired
    private GoodsBoxMapper goodsBoxMapper;

    @Autowired
    private GoodsBoxDetailService goodsBoxDetailService;

    @Autowired
    private RedisCache redisCache;

    @Autowired
    private WcsService wcsService;

    @Autowired
    private UpOrDownPolicyMapper upOrDownPolicyMapper;

    @Autowired
    private TemperatureZoneService temperatureZoneService;

    @Autowired
    private SaleOrderDetailMapper saleOrderDetailMapper;

    @Autowired
    private SaleOrderMapper saleOrderMapper;

    @Autowired
    private SpuMapper spuMapper;

    @Autowired
    private SpuSortRecordMapper spuSortRecordMapper;

    @Autowired
    private WarehousingEntryService warehousingEntryService;

    @Autowired
    private ProducerUtil producerUtil;

    /**
     * 查询货箱信息列表
     *
     * @param goodsBox 货箱信息
     * @return 货箱信息
     */
    @Override
    public List<GoodsBox> selectBoxlist(GoodsBox goodsBox) {
        return goodsBoxMapper.selectGoodsBoxList(goodsBox);
    }

    @Override
    public int insertGoodsBox(GoodsBox goodsBox) {
        return goodsBoxMapper.insert(goodsBox);
    }

    @Override
    public int updateGoodsBox(GoodsBox goodsBox) {
        return goodsBoxMapper.updateById(goodsBox);
    }

    @Override
    public int deleteGoodsBoxByIds(String ids) {
        String[] arrId = Convert.toStrArray(ids);
        for (String id : arrId) {
            goodsBoxMapper.deleteById(id);
        }
        return arrId.length;
    }

    @Override
    public int deleteGoodsBoxById(String id) {
        return goodsBoxMapper.deleteById(id);
    }

    /**
     * 分拣下架,获取货箱及详情
     *
     * @param spuId
     * @return
     * @author yw
     * @date 2022-04-17 14:01:42
     */
    @Override
    public GoodsBox sortByClient(String spuId) throws Exception {
        if (StrUtil.isEmpty(spuId)) {
            throw new UtilException("参数为空");
        }

        //货箱详情，不同入库单入同一个箱子，则同个供应商，同种原料会有多条
        List<GoodsBoxDetail> list = goodsBoxDetailService.selectBySpuId(spuId);
        if (!list.isEmpty()) {
            //获取货箱
            GoodsBox goodsBox = super.getOne(Wrappers.<GoodsBox>lambdaQuery().eq(GoodsBox::getBoxCode, list.get(0).getBoxCode()));
            goodsBox.setDetailList(list);
            return goodsBox;
        }
        return null;
    }

    /**
     * 获取货箱信息，包含详情
     *
     * @param boxCode
     * @return
     * @author yw
     * @date 2022-04-19 21:51:14
     */
    @Override
    public GoodsBox selectIncDetailByBoxCode(String boxCode) throws Exception {
        if (StrUtil.isEmpty(boxCode)) {
            throw new UtilException("参数为空");
        }
        GoodsBox goodsBox = goodsBoxMapper.selectOne(Wrappers.<GoodsBox>lambdaQuery().eq(GoodsBox::getBoxCode, boxCode));
        if (goodsBox != null) {
            //查询重量大于0的详情
            List<GoodsBoxDetail> list = goodsBoxDetailService.list(Wrappers.<GoodsBoxDetail>lambdaQuery().eq(GoodsBoxDetail::getBoxCode, goodsBox.getBoxCode()).gt(GoodsBoxDetail::getWeight, BigDecimal.ZERO));
            goodsBox.setDetailList(list);
            /*for (int i = 0; i < list.size(); i++) {
                GoodsBoxDetail goodsBoxDetail = list.get(i);
                *//**当前某分详情误差大于货箱误差时，认为有物品，小于货箱误差时，设置为当前详情分拣完毕，重量为0**//*
                if (goodsBoxDetail.getWeight().multiply(BigDecimal.valueOf(MqConstants.WCS_WEIGHT_UNIT_COEFFICIENT)).compareTo(goodsBox.getErrorMax()) > 0) {
                    goodsBox.setDetailList(list);
                } else {
                    goodsBox.setWeight(goodsBox.getWeight().subtract(goodsBoxDetail.getWeight()));
                    if (goodsBox.getWeight().multiply(BigDecimal.valueOf(MqConstants.WCS_WEIGHT_UNIT_COEFFICIENT)).compareTo(goodsBox.getErrorMax()) <= 0) {
                        goodsBox.setWeight(BigDecimal.ZERO);
                    }
                    goodsBoxDetail.setWeight(BigDecimal.ZERO);
                    goodsBoxDetailService.updateById(goodsBoxDetail);
                }
            }
            goodsBoxMapper.updateById(goodsBox);*/
        }
        return goodsBox;
    }

    /**
     * 调拨配送校验货箱
     *
     * @param param
     * @return com.lvy.hczn.model.front.GoodsBox
     * @author yw
     * @date 2022-05-07 14:43:45
     */
    @Override
    public GoodsBox sortByBoxCode(Param param) throws Exception {
        if (StrUtil.isEmpty(param.getGoodsBox().getBoxCode())) {
            throw new UtilException("货箱编号为空");
        }
        //查询条件：货箱编号&空箱&已下架
        GoodsBox box = super.getOne(Wrappers.<GoodsBox>lambdaQuery().eq(GoodsBox::getBoxCode, param.getGoodsBox().getBoxCode()).in(GoodsBox::getBoxType, Constants.GOODS_BOX_TYPE_ZERO, Constants.GOODS_BOX_TYPE_SIX).in(GoodsBox::getStatus, Constants.GOODS_BOX_STATE_TWO, Constants.GOODS_BOX_STATE_FIVE, Constants.GOODS_BOX_STATE_SIX));
        if (box == null) {
            throw new UtilException("货箱信息不存在");
        }
        return box;
    }

    /**
     * 根据货箱编号查空箱
     *
     * @param param
     * @return
     * @author yw
     * @date 2022-05-07 14:42:21
     */
    @Override
    public GoodsBox selectEmptyBoxByBoxCode(Param param) throws Exception {
        String boxCode = param.getGoodsBox().getBoxCode();
        if (StrUtil.isEmpty(boxCode)) {
            throw new UtilException("货箱编号为空");
        }
        //todo 货箱格式固定(LYG与12)，暂时先写死，后期有空再优化
        //todo 货箱入库前最好先备案到数据库，web每次扫描或者输入，都做一次校验，防止乱输入
        //todo 货箱编号有序，暂不开放非空箱货箱编号查询
        /*if (!boxCode.startsWith(Constants.PREFIX_BOX) || boxCode.length() != 12) {
            throw new UtilException("货箱不存在");
        }*/
        GoodsBox box;
        if (param.getBigProduct() != null && param.getBigProduct().equals(com.lvy.hczn.front.common.constant.Constants.GOODS_COLLECT_YES)) {
            box = super.getOne(Wrappers.<GoodsBox>lambdaQuery().eq(GoodsBox::getBoxCode, param.getGoodsBox().getBoxCode()));
        } else {
            box = super.getOne(Wrappers.<GoodsBox>lambdaQuery().eq(GoodsBox::getBoxCode, param.getGoodsBox().getBoxCode()).in(GoodsBox::getBoxType, Constants.GOODS_BOX_TYPE_ZERO, Constants.GOODS_BOX_TYPE_SIX));
        }

        if (box == null) {
            throw new UtilException("货箱信息不存在");
        }
        TemperatureZone temperatureZone = temperatureZoneService.getOne(Wrappers.<TemperatureZone>lambdaQuery().eq(TemperatureZone::getTemperatureZoneCode, String.valueOf(box.getActTemperatureCode())));
        if (temperatureZone != null) {
            box.setTemperatureName(temperatureZone.getName());
        }
        return box;
    }

    /**
     * 根据货箱编号急状态查询
     *
     * @param boxCode
     * @param status
     * @return
     */
    @Override
    public GoodsBox selectByBoxCodeAndStatus(String boxCode, String status) throws Exception {
        if (StrUtil.isAllEmpty(boxCode, status)) {
            throw new UtilException("参数为空");
        }
        return super.getOne(Wrappers.<GoodsBox>lambdaQuery().eq(GoodsBox::getBoxCode, boxCode).eq(GoodsBox::getStatus, status));
    }

    /**
     * 合并货箱，出库下个货箱，当缓存位和在途以及出库中都没有货箱的时候，
     * 再出库最后一个，防止就近出库，最后一个先到位
     *
     * @param clientId
     * @return void
     * @author yw
     * @date 2022-07-30 09:34:59
     */
    @Override
    public void downloadMergeBox(String clientId) throws Exception {
        if (StrUtil.isEmpty(clientId)) {
            throw new UtilException("参数为空");
        }
        Long size = redisCache.getListSize(CacheConstants.IN_BUFFER_POS + Constants.TYPE_WCS_RESPONSE + clientId);
        if (size == null || size == 0) {
            log.error("缓存位：{}", size);
            Long downloadNum = redisCache.getListSize(CacheConstants.SORT_TASK_DOWNLOAD + clientId);
            if (downloadNum == null || downloadNum == 0) {
                log.error("出库中：{}", size);
                List<UpOrDownPolicy> upOrDownPolicies = upOrDownPolicyMapper.selectList(Wrappers.<UpOrDownPolicy>lambdaQuery().eq(UpOrDownPolicy::getType, Constants.BOX_OPERATION_DOWN).eq(UpOrDownPolicy::getProcessType, Constants.STATE_PROCESS_TYPE_ONE).eq(UpOrDownPolicy::getClientId, clientId));
                if (upOrDownPolicies == null || upOrDownPolicies.isEmpty()) {
                    log.error("在途：{}", JSONUtil.toJsonStr(upOrDownPolicies));
                    Object object = redisCache.delListLeftPop(CacheConstants.MERGE_BOX + clientId);
                    if (object != null) {
                        String boxCode = String.valueOf(object);

                        Param param = new Param();
                        UpOrDownPolicy upOrDownPolicy = new UpOrDownPolicy();
                        upOrDownPolicy.setClientId(clientId);
                        upOrDownPolicy.setBoxType(Constants.GOODS_BOX_TYPE_SPU);
                        upOrDownPolicy.setBoxCode(boxCode);
                        param.setOutboundAndEntry(true);
                        param.setUpOrDownPolicy(upOrDownPolicy);
                        redisCache.setListOfLeft(CacheConstants.SORT_TASK_DOWNLOAD + clientId, boxCode);
                        try {
                            log.error("downloadMergeBox出库：" + JSONUtil.toJsonStr(param));
                            wcsService.sortingOutBatch(param, false);
                        } catch (Exception e) {
                            redisCache.setListOfLeft(CacheConstants.MERGE_BOX + clientId, boxCode);
                            throw new UtilException("合箱出库忙碌中，请稍后重试！");
                        }
                    }
                }
            }

        }
    }

    /**
     * 销售退货商品入库，查询退货商品所对应的温区下架容量剩余最多的一个货箱
     *
     * @param clientId
     * @return void
     * @author yw
     * @date 2023-09-13 22:36:36
     */
    @Override
    public void downloadReturnBox(String clientId) throws Exception {
        Long size = redisCache.getListSize(CacheConstants.IN_BUFFER_POS + Constants.TYPE_WCS_RESPONSE + clientId);
        if (size == null || size == 0) {
            log.error("downloadReturnBox缓存位：{}", size);
            Long downloadNum = redisCache.getListSize(CacheConstants.SORT_TASK_DOWNLOAD + clientId);
            if (downloadNum != null && downloadNum == 0) {
                GoodsBox box = new GoodsBox();
                //获取退货商品是spuId,从而从spu表获取温区信息
                /*可以从页面获取温区下架，不过暂时从后台查询**/
                String statusStr = com.lvy.hczn.front.common.constant.Constants.SALE_ORDER_STATUS_THREE;
                List<SaleOrder> saleOrderList = saleOrderMapper.selectList(Wrappers.<SaleOrder>lambdaQuery().eq(SaleOrder::getStatus, statusStr).in(SaleOrder::getType, com.lvy.hczn.front.common.constant.Constants.SALE_ORDER_TYPE_TWO, com.lvy.hczn.front.common.constant.Constants.SALE_ORDER_TYPE_FOUR));
                List<SaleOrderDetail> saleOrderDetails = new ArrayList<>();
                saleOrderList.forEach(saleOrder -> {
                    List<SaleOrderDetail> saleOrderDetailList = saleOrderDetailMapper.selectList(Wrappers.<SaleOrderDetail>lambdaQuery().eq(SaleOrderDetail::getSaleOrderCode, saleOrder.getSaleOrderCode()).eq(SaleOrderDetail::getDataType, com.lvy.hczn.front.common.constant.Constants.WAREHOUSING_ENTRY_DATA_TYPE_SEVEN).eq(SaleOrderDetail::getStatus, com.lvy.hczn.front.common.constant.Constants.SALE_ORDER_DETAIL_STATUS_THREE));
                    if (!saleOrderDetailList.isEmpty()) {
                        saleOrderDetails.addAll(saleOrderDetailList);
                    }
                });

                if (saleOrderDetails.isEmpty()) {
                    throw new UtilException("当前无退货商品");
                }

                //获取温区列表
                List<Integer> temperZoneList = new ArrayList<>();
                LinkedHashMap<String, List<SaleOrderDetail>> map = saleOrderDetails.stream().filter(model -> !StrUtil.isEmpty(model.getSpuId())).collect(Collectors.groupingBy(SaleOrderDetail::getSpuId, LinkedHashMap::new, Collectors.toList()));
                if (!map.isEmpty()) {
                    map.forEach((k, v) -> {
                        Spu spu = spuMapper.selectById(k);
                        if (spu != null) {
                            temperZoneList.add(spu.getTemperatureZoneCode());
                        }
                    });
                }

                box.setWarehouseNumber(Integer.valueOf(clientId));
                if (temperZoneList.isEmpty()) {
                    throw new UtilException("退货商品不在此仓库温区！");
                }
                List<GoodsBox> goodsBoxes = goodsBoxMapper.downloadReturnBox(box, temperZoneList);
                if (goodsBoxes.isEmpty()) {
                    throw new UtilException("当前仓库无退货物品！");
                }
                //获取每个温区的一个货箱，退货入库商品，只能放入相同温区的货箱
                LinkedHashMap<String, List<GoodsBox>> mapTemper = goodsBoxes.stream().collect(Collectors.groupingBy(GoodsBox::getActTemperatureCode, LinkedHashMap::new, Collectors.toList()));
                List<Object> boxCodeList = new ArrayList<>();
                mapTemper.forEach((k, v) -> {
                    boxCodeList.add(v.get(0).getBoxCode());
                });

                /*执行货箱下架**/
                Param param = new Param();
                UpOrDownPolicy upOrDownPolicy = new UpOrDownPolicy();
                upOrDownPolicy.setClientId(clientId);
                upOrDownPolicy.setBoxType(Constants.GOODS_BOX_TYPE_SPU);
                param.setOutboundAndEntry(true);
                param.setUpOrDownPolicy(upOrDownPolicy);
                redisCache.setAllListOfRight(CacheConstants.SORT_TASK_DOWNLOAD + clientId, boxCodeList);
                try {
                    log.error("downloadReturnBox出库：{}", JSON.toJSONString(param));
                    wcsService.sortingOutBatch(param, false);
                } catch (Exception e) {
                    throw new UtilException("退货入库当前仓库忙碌中，请稍后重试！");
                }
            } else {
                throw new UtilException("退货入库当前有下架任务，请稍后重试！");
            }
        } else {
            log.error("downloadReturnBox:当前缓存位有任务，请稍后重试！");
        }
    }

    /**
     * 临期报损出库下架货箱
     *
     * @param clientId
     * @return void
     * @author yw
     * @date 2023-09-16 20:44:35
     */
    @Override
    public void downloadFrmLossBox(String clientId) throws Exception {
        Long size = redisCache.getListSize(CacheConstants.IN_BUFFER_POS + Constants.TYPE_WCS_RESPONSE + clientId);
        if (size == null || size == 0) {
            log.error("downloadFrmLossBox缓存位：{}", size);
            Long downloadNum = redisCache.getListSize(CacheConstants.SORT_TASK_DOWNLOAD + clientId);
            if (downloadNum != null && downloadNum == 0) {
                LambdaQueryWrapper<SpuSortRecord> queryWrapper = new LambdaQueryWrapper<>();
                queryWrapper.eq(SpuSortRecord::getTreated, false);
                queryWrapper.eq(SpuSortRecord::getType, String.valueOf(com.lvy.hczn.front.common.constant.Constants.FRM_LOSS_DATA_TYPE_ONE));
                queryWrapper.eq(SpuSortRecord::getStatus, com.lvy.hczn.front.common.constant.Constants.FRM_LOSS_DATA_TYPE_ONE);
                queryWrapper.eq(SpuSortRecord::getDataType, com.lvy.hczn.front.common.constant.Constants.WAREHOUSING_ENTRY_DATA_TYPE_FIVE);
                List<SpuSortRecord> spuSortRecordList = spuSortRecordMapper.selectList(queryWrapper);
                if (spuSortRecordList.isEmpty()) {
                    throw new UtilException("当前仓库无临期出库物品！");
                }

                List<GoodsBox> list = new ArrayList<>();
                spuSortRecordList.forEach(spuSortRecord -> {
                    List<GoodsBox> boxDetails = goodsBoxMapper.selectFrmLossList(spuSortRecord);
                    if (!boxDetails.isEmpty()) {
                        list.addAll(boxDetails);
                    }
                });

                String vBoxCode = DictUtils.getDictValue(com.lvy.hczn.front.common.constant.Constants.VIRTUALLY_BOX_GOODS, com.lvy.hczn.front.common.constant.Constants.VIRTUALLY_BOX_GOODS_BOX_CODE);

                //货箱去重
                LinkedHashMap<Object, Boolean> map = new LinkedHashMap<>();
                List<GoodsBox> objectListBox;
                if (StrUtil.isEmpty(vBoxCode)) {
                    objectListBox = list.stream().filter(i -> map.putIfAbsent(i.getBoxCode(), Boolean.TRUE) == null).collect(Collectors.toList());
                } else {
                    objectListBox = list.stream().filter(item -> !item.getBoxCode().equals(vBoxCode)).filter(i -> map.putIfAbsent(i.getBoxCode(), Boolean.TRUE) == null).collect(Collectors.toList());
                }

                //只取货箱编号
                List<Object> objectList = objectListBox.stream().map(GoodsBox::getBoxCode).collect(Collectors.toList());
                log.error("临期出库货箱：{}", JSON.toJSONString(objectList));
                if (!objectList.isEmpty()) {
                    boolean result = redisCache.setAllListOfRight(CacheConstants.SORT_TASK_DOWNLOAD + clientId, ListUtil.sub(objectList, 0, objectList.size()));
                    if (result) {
                        downloadFrmBox(clientId);
                    }
                }

            } else {
                downloadFrmBox(clientId);
//                throw new UtilException("当前有下架任务，请稍后重试！");
            }
        } else {
            log.error("downloadFrmLossBox:当前缓存位有任务，请稍后重试！");
        }
    }

    public void downloadFrmBox(String clientId) {
        Param param = new Param();
        UpOrDownPolicy upOrDownPolicy = new UpOrDownPolicy();
        upOrDownPolicy.setClientId(clientId);
        upOrDownPolicy.setBoxType(Constants.GOODS_BOX_TYPE_SPU);
        param.setOutboundAndEntry(true);
        param.setUpOrDownPolicy(upOrDownPolicy);
        try {
            log.error("downloadFrmLossBox出库：" + JSONUtil.toJsonStr(param));
            wcsService.sortingOutBatch(param, false);
        } catch (Exception e) {
            throw new UtilException("临期出库忙碌中，请稍后重试！");
        }
    }

    /**
     * 空箱或指定货箱出库
     *
     * @param param
     * @return com.lvy.hczn.common.core.util.ResultUtil
     * @author yw
     * @date 2022-07-29 15:52:12
     */
    @Override
    public void downloadEmptyBox(Param param) {
        if (param == null || param.getGoodsBox() == null) {
            throw new UtilException("货箱参数信息不能为空！");
        }
        if (StrUtil.isEmpty(param.getGoodsBox().getBoxCode())) {
            throw new UtilException("货箱编号不能为空！");
        }
        GoodsBox goodsBox = goodsBoxMapper.selectOne(Wrappers.<GoodsBox>lambdaQuery().eq(GoodsBox::getBoxCode, param.getGoodsBox().getBoxCode()).last("limit 1"));
        if (goodsBox == null) {
            throw new UtilException("货箱信息不存在！");
        }
        List<GoodsBox> list = new ArrayList<>();
        list.add(goodsBox);
        //空货箱出入库库，不做库位调整
//        warehousingEntryService.boxShelfLocationMsg(null, list, true);
    }

    /**
     * 调拨分拣完成货箱信息列表
     *
     * @param goodsBox
     * @return
     * @author yw
     * @date 2023-08-20 16:10:18
     */
    @Override
    public List<GoodsBox> selectTransferSortDoneByOutBoundOrderCode(GoodsBox goodsBox) {
        if (StrUtil.isEmpty(goodsBox.getOutboundOrderCode())) {
            throw new UtilException("出库单号不能为空！");
        }
        return goodsBoxMapper.selectTransferSortDoneByOutBoundOrderCode(goodsBox);
    }

    /**
     * 临期报损查询货箱
     *
     * @param spuSortRecord
     * @return
     */
    @Override
    public List<GoodsBox> selectFrmLossList(SpuSortRecord spuSortRecord) {
        if (StrUtil.hasEmpty(spuSortRecord.getSpuId(), spuSortRecord.getSkuCode())) {
            throw new UtilException("商品ID为空");
        }
        if (spuSortRecord.getProductDate() == null) {
            throw new UtilException("生产日期为空");
        }
        List<GoodsBox> list = new ArrayList<>();
        return list;
    }

    /**
     * @Description 新货箱称重同步到数据转发中心
     * @Param [goodsBox]
     * @Author yw
     * @Date 2024/4/26 9:56
     * @Return void
     **/
    public void netWeightSyncToPlatform(GoodsBox goodsBox) throws Exception {
        ParamInfo<GoodsBox> info = new ParamInfo<>();
        info.setWarehouseCode(goodsBox.getWarehouseCode());
        info.setData(goodsBox);
        try {
            producerUtil.sendAsyncMsg(MqConstants.TOPIC_NET_WEIGHT, null, JSON.toJSONStringWithDateFormat(info, JSON.DEFFAULT_DATE_FORMAT).getBytes(StandardCharsets.UTF_8), IdUtil.fastSimpleUUID());
        } catch (Exception e) {
            log.error("新货箱净重称重发送异常:", e);
            throw new UtilException(e);
        }
    }

    /**
     * 分拣称重完成，则检查货箱商品重量是否为空箱,为空箱，则进行库位调整同步到平台
     *
     * @param boxCode
     * @return
     * @author yw
     * @date 2022-04-19 21:51:14
     */
    @Override
    public void checkShelfLocation(String boxCode) throws Exception {
        GoodsBox goodsBox = selectIncDetailByBoxCode(boxCode);
        log.error("分拣称重完成，验证货箱是否变成空箱，checkShelfLocation：{}", JSON.toJSONString(goodsBox));
        if (goodsBox != null && goodsBox.getDetailList().isEmpty()) {
            ThreadUtil.execAsync(() -> {
                //原料箱变空箱后，库位调整，释放库位
                warehousingEntryService.boxShelfLocationMsgSingle(goodsBox, true);
            });
        }
    }

    /**
     * @Description 离开缓存位后获取货箱数据
     * @Param
     * @Author yw
     * @Date 2024/6/22 15:40
     * @Return
     **/
    @Override
    public GoodsBox getGoodsBoxByKey(UpOrDownPolicy upOrDownPolicy) {
        //货箱入库离开库位响应再保存货箱信息
        String boxKey = CacheConstants.WCS_RESPONSE + upOrDownPolicy.getBoxCode() + ":" + upOrDownPolicy.getProcessType();
        Param paramInfo = redisCache.getCacheObject(boxKey);
        GoodsBox goodsBox = null;
        if (paramInfo != null) {
            if (paramInfo.getGoodsBox() != null) {
                boolean fl = this.saveOrUpdate(paramInfo.getGoodsBox());
                goodsBox = paramInfo.getGoodsBox();
                if (fl && paramInfo.getList() != null && !paramInfo.getList().isEmpty()) {
                    goodsBoxDetailService.saveOrUpdateBatch(paramInfo.getList());
                    paramInfo.setGoodsBox(goodsBox);
                    redisCache.set(boxKey, paramInfo, 3, TimeUnit.DAYS);
                }
            }
        }
        return goodsBox;
    }
}
